/*
 * Copyright (C) 拾光分享网 
 * All rights reserved, Designed By www.hiai.top.
 * Email：goodsking@163.com.
 */
package top.hiai.config;

import com.jfinal.config.*;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.render.JsonRender;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;

import top.hiai._admin.auth.AdminAuthKit;
import top.hiai._admin.common.AdminRoutes;
import top.hiai._admin.permission.PermissionDirective;
import top.hiai._admin.role.RoleDirective;
import top.hiai.common.interceptor.LoginSessionInterceptor;
import top.hiai.common.model._MappingKit;
import top.hiai.login.LoginService;

/**
* @Author www.hiai.top
* @Email  goodsking@163.com
* @Message 更多资源尽在www.hiai.top
* @Introduction 类的介绍 项目运行
*/

public class AppConfig extends JFinalConfig {
    static Prop p;
    /**
     * 注意：用于启动的 main 方法可以在任意 java 类中创建，在此仅为方便演示
     *      才将 main 方法放在了 DemoConfig 中
     *
     *      开发项目时，建议新建一个 App.java 或者 Start.java 这样的专用
     *      启动入口类放置用于启动的 main 方法
     */
    public static void main(String[] args) {
    	 UndertowServer.start(AppConfig.class);
    	//JFinal.start("src/main/webapp", 8081, "/");
    }

    /**
     * PropKit.useFirstFound(...) 使用参数中从左到右最先被找到的配置文件
     * 从左到右依次去找配置，找到则立即加载并立即返回，后续配置将被忽略
     */
    static void loadConfig() {
        if (p == null) {
            p = PropKit.useFirstFound("demo-config-pro.txt", "demo-config-dev.txt");
        }
    }

    /**
     * 配置常量
     */
    public void configConstant(Constants me) {
        loadConfig();

        me.setDevMode(p.getBoolean("devMode", false));

        /**
         * 支持 Controller、Interceptor、Validator 之中使用 @Inject 注入业务层，并且自动实现 AOP
         * 注入动作支持任意深度并自动处理循环注入
         */
        me.setInjectDependency(true);

        // 配置对超类中的属性进行注入
        me.setInjectSuperClass(true);
        //配置404界面
        me.setError404View("/_view/error/404.html");
    }

    /**
     * 配置路由
     */
    public void configRoute(Routes me) {
        me.add(new FrontRoutes());
        me.add(new AdminRoutes());
    }

    /**
     * 配置前台模板
     * @param me
     */
    public void configEngine(Engine me) {
    	
		// 添加角色、权限指令
		me.addDirective("role", RoleDirective.class);
		me.addDirective("permission", PermissionDirective.class);
		me.addDirective("perm", PermissionDirective.class);		// 配置一个别名指令

		// 添加角色、权限 shared method
		me.addSharedMethod(AdminAuthKit.class);
        
    	me.addSharedFunction("/_view/common/_layout.html");
        me.addSharedFunction("/_view/common/_paginate.html");
        
	    me.addSharedFunction("/_view/_admin/common/_admin_layout.html");
		me.addSharedFunction("/_view/_admin/common/_admin_paginate.html");
    }

    /**
     * 配置插件
     */
    public void configPlugin(Plugins me) {
        // 配置 druid 数据库连接池插件
        DruidPlugin druidPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password").trim());
        me.add(druidPlugin);

        // 配置ActiveRecord插件
        ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
        // 所有映射在 MappingKit 中自动化搞定
        _MappingKit.mapping(arp);
        me.add(arp);
        arp.getEngine().setSourceFactory(new ClassPathSourceFactory());
        arp.addSqlTemplate("/sql/all_sqls.sql");
        
        me.add(new EhCachePlugin());
    }

    public static DruidPlugin createDruidPlugin() {
        loadConfig();
        return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password").trim());
    }

    /**
     * 配置全局拦截器
     */
    public void configInterceptor(Interceptors me) {
    	me.add(new LoginSessionInterceptor());
    }

    /**
     * 配置处理器
     */
    public void configHandler(Handlers me) {}
    
    /**
     * 本方法会在 jfinal 启动过程完成之后被回调，详见 jfinal 手册
     */
	public void afterJFinalStart() {
		// 调用不带参的 renderJson() 时，排除对 loginAccount、remind 的 json 转换
		JsonRender.addExcludedAttrs(
                LoginService.loginAccountCacheName,
                LoginSessionInterceptor.remindKey
        );
	}
}